from rest_framework import serializers, status

from .models.cc import CC
from .models.cure import Cure
from .models.summary import Summary
from .models.results import Results
from .models.history import History
from .models.relevant import Relevant
from .models.geninfo import GeneralInfo
from .models.models import InvestFileUpload

from .utils.create import update_model
from .utils.create import update_every_table

from .decorators import serializer_decorator
from .decorators import moblie_serializer_decorator

from .utils.excelconstants import upload_file_type
from .utils.serials import create_serial, find_today_max

from django.db.utils import IntegrityError


class GenInfoSerializer(serializers.HyperlinkedModelSerializer):
    menstruation = serializers.HyperlinkedRelatedField(read_only=True,
                                                       view_name='menstruation-detail',
                                                       label='月经带下史')
    cc = serializers.HyperlinkedRelatedField(view_name='cc-detail',
                                             read_only=True,
                                             label='临床诊断')
    cure = serializers.HyperlinkedRelatedField(view_name='cure-detail',
                                               read_only=True,
                                               label='治疗')
    summary = serializers.HyperlinkedRelatedField(view_name='summary-detail',
                                                  read_only=True,
                                                  label='就诊时病情概要')
    results = serializers.HyperlinkedRelatedField(view_name='results-detail',
                                                  read_only=True,
                                                  label='疗效')
    history = serializers.HyperlinkedRelatedField(view_name='history-detail',
                                                  read_only=True,
                                                  label='病史')
    relevant = serializers.HyperlinkedRelatedField(view_name='relevant-detail',
                                                   read_only=True,
                                                   label='相关检查')
    owner = serializers.SlugRelatedField(label='辅助医生',
                                         read_only=True,
                                         slug_field='user_name')

    class Meta:
        model = GeneralInfo
        fields = ('url', 'id', 'menstruation', 'cc', 'cure',
                  'summary', 'results', 'history', 'relevant',
                  'is_checked', 'degree_of_completion',
                  'owner', 'serial', 'name', 'hospital', 'expert',
                  'address', 'reasons_for_not_passing')
        read_only_fields = ('menstruation', 'cc', 'cure',
                            'summary', 'results', 'history', 'relevant',
                            'is_checked', 'degree_of_completion', 'reasons_for_not_passing')


@serializer_decorator(model_obj=CC)
class CCSerializer(serializers.HyperlinkedModelSerializer):
    pass


@serializer_decorator(model_obj=Cure, type='cure_degree')
class CureSerializer(serializers.HyperlinkedModelSerializer):
    pass


@serializer_decorator(model_obj=Summary)
class SummarySerializer(serializers.HyperlinkedModelSerializer):
    pass


@serializer_decorator(model_obj=Results)
class ResultsSerializer(serializers.HyperlinkedModelSerializer):
    pass


@serializer_decorator(model_obj=History)
class HistorySerializer(serializers.HyperlinkedModelSerializer):
    pass


@serializer_decorator(model_obj=Relevant)
class RelevantSerializer(serializers.HyperlinkedModelSerializer):
    pass


class UploadExcelSerializer(serializers.ModelSerializer):

    class Meta:
        model = InvestFileUpload
        fields = '__all__'
        read_only_fields = ('owner', )

    def validate(self, data):
        ivfile = data.get('ivfile', None)
        if not ivfile:
            raise serializers.ValidationError('未选择上传文件')
        file_type = ivfile.name.split('.')[-1]
        if file_type not in upload_file_type:
            raise serializers.ValidationError('上传文件类型不允许(只允许%s)' % '/'.join(upload_file_type))
        return data


class FileDownloadIDSerializer(serializers.Serializer):
    idList = serializers.ListField(required=True,
                                   child=serializers.IntegerField(required=True))

    def validate(self, data):
        id_ = data.get('idList', None)
        if not id_:
            raise serializers.ValidationError(detail='传递参数为空',
                                              code=status.HTTP_402_PAYMENT_REQUIRED)
        if not isinstance(id_, list):
            raise serializers.ValidationError(detail='参数类型错误',
                                              code=status.HTTP_402_PAYMENT_REQUIRED)
        return data


class OtherTablesSerializer(serializers.Serializer):
    cc = CCSerializer()
    cure = CureSerializer()
    summary = SummarySerializer()
    results = ResultsSerializer()
    history = HistorySerializer()
    relevant = RelevantSerializer()


class DataSerializer(serializers.Serializer):
    data = serializers.CharField(help_text='表单信息')


class SearchSerializer(serializers.Serializer):
    name = serializers.CharField(help_text='患者姓名', required=False)
    address = serializers.CharField(help_text='地址', required=False)
    telephone = serializers.IntegerField(help_text='手机', required=False)
    hospital = serializers.CharField(help_text='医院', required=False)
    is_checked = serializers.CharField(help_text='审核状态', required=False)

    # 针对用户进行查询
    owner__user_name = serializers.CharField(help_text='医生姓名', required=False)
    owner__hospital = serializers.CharField(help_text='医生所在医院', required=False)

    types = serializers.CharField(help_text='类型',
                                  required=True,
                                  write_only=True)


class CheckedSerializer(serializers.Serializer):
    is_checked = serializers.CharField(help_text='审核状态',
                                       required=True)
    reasons_for_not_passing = serializers.CharField(help_text='审核不通过原因',
                                                    required=False)

    def validate_is_checked(self, value):
        if value not in ('未审核', '审核通过', '审核不通过'):
            raise serializers.ValidationError('该状态不存在')
        return value


class InfoSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.SlugRelatedField(label='辅助医生',
                                         read_only=True,
                                         slug_field='email')

    class Meta:
        model = GeneralInfo
        fields = '__all__'
        read_only_fields = ('serial',
                            'is_checked',
                            'degree_of_completion')

    def create(self, data):
        user = self.context['view'].request.user
        degree = update_model(data, user=user)

        serial = create_serial()

        gen = GeneralInfo(owner=user,
                          serial=serial,
                          degree_of_completion='%.2f%%' % (degree * 100),
                          **data)
        try:
            gen.save()
        except IntegrityError:
            serial = find_today_max()
            gen = GeneralInfo(owner=user,
                              serial=serial,
                              degree_of_completion='%.2f%%' % (degree * 100),
                              **data)
            gen.save()

        return gen

    def update(self, instance, data):
        user = instance.owner
        data['serial'] = instance.serial
        # is_checked = instance.is_checked
        return update_every_table(instance, data, tps='info', user=user)


@moblie_serializer_decorator(CC)
class MCCSerializer(serializers.ModelSerializer):
    pass


@moblie_serializer_decorator(Cure)
class MCureSerializer(serializers.ModelSerializer):
    pass


@moblie_serializer_decorator(Summary)
class MSummarySerializer(serializers.ModelSerializer):
    pass


@moblie_serializer_decorator(Results)
class MResultsSerializer(serializers.ModelSerializer):
    pass


@moblie_serializer_decorator(History)
class MHistorySerializer(serializers.ModelSerializer):
    pass


@moblie_serializer_decorator(Relevant)
class MRelevantSerializer(serializers.ModelSerializer):
    pass


class ChartsSerializer(serializers.Serializer):
    pass
